perm filename SEGMEN.SAI[SYS,HE]2 blob sn#017845 filedate 1972-12-06 generic text, type T, neo UTF8
COMMENT ⊗   VALID 00019 PAGES 
RECORD PAGE   DESCRIPTION
 00001 00001
 00003 00002	BEGIN "SEGMENTER"
 00004 00003	α INTERNAL DECLARATIONS
 00006 00004	α	MESSAGE PROCEDURE SEGMENT - (START OF EXECUTION)
 00007 00005	α	SCENE DESCRIPTION
 00009 00006	α	SET UP THE SCENE
 00013 00007	α	***** CLASSIFY VERTICES. *****
 00016 00008	α	 LPAIR HACK
 00018 00009	α	DISJOINT
 00019 00010	α	FIXUP 1, FIXUP 2
 00021 00011	α	TRY1, TRY2, TRY3
 00024 00012	α	TRY4, TRY5
 00025 00013	α	FIXUP THE LOCAL DATA STRUCTURE, SPLICE
 00027 00014	α	ABOVE, OCCLUDERS, EXTERIOR
 00029 00015	α	PROPOSER - FIX UP THE BODIES
 00034 00016	α	GLOBAL STRUCTURE FOR BODIES:
 00036 00017	α	SET UP GLOBAL BODY STRUCTURE
 00039 00018	α  OTHER GLOBAL ASSOCIATIONS:
 00040 00019	α	PROGRAM EXECUTION
 00043 ENDMK
⊗;
BEGIN "SEGMENTER"

   REQUIRE	1000	PNAMES;
   REQUIRE	1000	NEW_ITEMS;
   REQUIRE	"PREAMB.SAI[SYS,HE]"	SOURCE_FILE;
   REQUIRE	"SYMBOL.AUX[H,RPO]"	SOURCE_FILE;
   REQUIRE	"SEGDPY.HDR[SYS,HE]"	SOURCE_FILE;
   REQUIRE	"SEGMEN.AUX[SYS,HE]"	SOURCE_FILE;

DEFINE
	MERGE(X)=<MERGED[X]←MERGED[X]+1>,
	GLB=<GLOBAL>,
	ZEROS=<11>,INUM=<12>;

α LOCALS;

SET ITEMVAR NN,XS;
REAL ITEMVAR XR;
SAFE REAL ARRAY ITEMVAR PY,XRA;
SET COLINE,SSET;
SAFE REAL ARRAY ITEMVAR GB,GB1,GB2;
INTEGER MESS1;
SAFE REAL ARRAY ITEMVAR CP,CF,CR;
REAL ITEMVAR CL;

α INTERNAL DECLARATIONS;


INTERNAL ITEMVAR
	T_STEM,REASON,EXTERIOR,NFLAVOR,ITEM1,ITEMN,
	TMPATR,
	IMATCH,NMATCH,OMATCH,BMATCH,CMATCH,
	MATCH,MATCH2,
	TPAIR,GRAPH,NODE,LINK,NOFLAVOR,S,BACK,
	F1,F,BB1,BB2,LX,E1,E2,R,R1,R2,L,L1,L2,L3,L4,C,B1,B2;
INTERNAL INTEGER ITEMVAR
	LPAIR,NEWP,NEWL,NEWR,NEWF,NEWB;
INTERNAL SET ITEMVAR
	SIV,X,Y,Z;
INTERNAL SAFE REAL ARRAY ITEMVAR U,V,W,PX,P,P1,P2,P3,P4,XX,YY,B,P5;

INTERNAL STRING STR,STR1;
INTERNAL INTEGER DEBUG2,IFLAG,ERRFLAG;
INTERNAL SAFE REAL ARRAY
	FOURBY4[1:4,1:4],SIZE4[1:4],SIZE7[1:7];
INTERNAL INTEGER I,J,K,X1,X2,Y1,Y2,BBADLCNT,
	ADCOR1,ADCOR2;
INTERNAL BOOLEAN BOOL;
INTERNAL SET
	AROOUT,DOUBLE,SHAFTS,TTOPS,KTOPS,TSTEMS,SOP,PRSET,SX,S3,
	S1,S2,S4,S5,P_SET,NO_CLASS,NEWPOINTS,BACKSET;

INTERNAL SAFE INTEGER ARRAY MERGED[0:4];

α	MESSAGE PROCEDURE SEGMENT - (START OF EXECUTION);

MESSAGE PROCEDURE SEGMENT;
BEGIN	"MP SEGMENT"
      INTEGER II,JJ,FILE,BREAK,EOF;
      LABEL LAB4,LAB5,LAB6,INLAB;

      α ***	PROGRAMME AND SCENE INITIALIZATION	***;

      DEBUG2←TRUE;

β	DPYINIT;

α	SCENE DESCRIPTION
this file input routine is temporary - i.e. til used
actively in the he system, at which time this data will be all ready up
in the global model.  Copy it locally to the segmenter and delete
all the global cruft copied.  This program is plagued by too many
copies of data locally and globally....
lines,vertices, coordinates and regions are read from the global model...
the next page sets up the following initial LOCAL data structure:
	S ← SCENE (GLOBAL ITEM)
	POINT⊗S≡<picture vertex>	(NEW)
		∂(<vertex>)[1] ← <x coor>
		∂(<vertex>)[2] ← <y coor>
		∂(<vertex>)[6] ← <display x coor>
		∂(<vertex>)[7] ← <display y coor>
	LINE⊗S≡<picture line>		(NEW)
		ENDPT⊗<line>≡<vertex>
		ENDPT⊗<line>≡<vertex>
	REGION⊗S≡<picture region>	(NEW)
		CORNER⊗<region>≡<vertex>	n times
		BOUNDARY⊗<region>≡<line>	n times
	BACKGROUND⊗s≡<region>

	IMATCH⊗<global input item>≡<local item>		(input match)
if EDGE isn't around to set up the global model, then DATA_MAKER is called
to set up the global structure from file input.
;

α	SET UP THE SCENE
;

IF ¬YES_EDGE
THEN DATA_MAKER;

DPYTELL("SET UP THE SCENE");
S←SCENE;

BEGIN "SCENE"
	SAFE REAL ARRAY ITEMVAR H,T,FIRSTT,P,GP,XF;
	INTEGER ITEMVAR L,GL;
	ITEMVAR IV1,R,GR,GBACK;
	LIST ITEMVAR GPERI;
	INTEGER AB,PATHS,K,NUMBER,I,II,J,FLAG,FLAGH,FLAGT;
	SET SE;
	STRING STRN ;

DPYTELL("GET VERTICES AND COORDINATES");
NUMBER←0;
       ∀ GP|GLOBAL POINT⊗S≡GP DO
	BEGIN "POINTS"
		P ←NEW(SIZE7);
		STRN←"P"&CVS(NUMBER←NUMBER+1);
		NEW_PNAME(P,STRN);
		ARRTRAN(∂(P),GLB ∂(GP));
		MAKE POINT⊗S≡P;
		MAKE IMATCH⊗GP≡P;
		END "POINTS";
∂(NEWP)←NUMBER;
DPYVINIT;

DPYTELL("GET LINES AND ENDPOINTS" );
NUMBER←0;
      ∀ GL|GLB LINE⊗S≡GL DO
	BEGIN "LINES"
		L←NEW(0.0);
		STRN←"L"&CVS(NUMBER←NUMBER+1);
		NEW_PNAME(L,STRN);
		MAKE LINE⊗S≡L;
		MAKE IMATCH⊗GL≡L;
		∀ GP| GLB ENDPT⊗GL≡GP DO
		BEGIN "ENDPT"
			ASSIGN P|IMATCH⊗GP≡P HOLDS;
			MAKE ENDPT⊗L≡P;
			END "ENDPT";
		END "LINES";
∂(NEWL)←NUMBER;

DPYTELL( "GET REGIONS AND CORNERS");
NUMBER←0;
∀ GR|GLOBAL REGION⊗S≡GR DO
BEGIN "REGIONS"
	R ← NEW;
	STRN←"R"&CVS(NUMBER←NUMBER+1);
	NEW_PNAME(R,STRN);
	MAKE REGION⊗S≡R;
	MAKE IMATCH⊗GR≡R;
	ASSIGN GPERI|GLB PERIMETER⊗GR≡GPERI HOLDS;
	II ←LENGTH(GLB ∂(GPERI));
	BEGIN "B AND C"
	 GP←GLB ∂(GPERI)[II];
 	 ASSIGN FIRSTT|IMATCH⊗GP≡FIRSTT HOLDS;
	 FOR J←1 STEP 1 UNTIL II DO
	 BEGIN "B1"
	  IF J=1 THEN T←FIRSTT ELSE T←H;
	  GP←GLB ∂(GPERI)[J];
	  ASSIGN H|IMATCH⊗GP≡H HOLDS;
	  SE← (ENDPT`H) ∩ (ENDPT`T);
	  L←COP(SE);
	  MAKE BOUNDARY⊗R≡L;
	  MAKE CORNER⊗R≡H;
	  END "B1";
	 END "B AND C";
	END "REGIONS";
∂(NEWR)←NUMBER;

DPYTELL("ASSIGN BACKGROUND");
	ASSIGN GBACK|GLOBAL BACKGROUND⊗S≡GBACK HOLDS;
	ASSIGN BACK|IMATCH⊗GBACK≡BACK HOLDS;
	MAKE BACKGROUND⊗S≡BACK;

α just may need the inverse camera transform !;
DPYTELL("INVERSE TRANSFORM");
	ASSIGN XF|GLB XFORM⊗S≡XF HOLDS;
	ARRBLT(AI_REC[1,1],GLB ∂(XF)[6,1],9);

END "SCENE";

TYPE "ALL DONE!" EOM;

α	***** CLASSIFY VERTICES. *****;
      DPYTELL( "CLASSIFY VERTICES." );

α the LOCAL data structure is embellished by classifying vertices
and the creation of the node graph:
	FLAVOR⊗<vertex>≡<flavor>	(read the thesis)
	OCCLUDER⊗<line>≡<line>
	T_STEM⊗<vertex>≡<line>

	NODE⊗GRAPH≡<new(phi)>
	NMATCH⊗<node item>≡<creating vertex>
	NFLAVOR⊗<node>≡<matching vertex flavor>

	LINK⊗<node>≡<node>
	ABOVE⊗<node>≡<node>
	BMATCH⊗<node item>≡<body item>
	(CMATCH⊗<scene vertex or line>≡<body vertex or line>)
	OMATCH⊗<global item>≡<local item>	(output match)
;	
α	***** CREATE GRAPH NODES AND DETERMINE FLAVORS *****;

      SHAFTS←TSTEMS←TTOPS←KTOPS←AROOUT←SOP←PHI;
      PRSET←{LPAIR,GOODY,ARROW,GOODL,TJOINT,GOODX,BADX,KJOINT};

      ∀ P|POINT⊗S≡P ∧ (¬(PεSOP)) DO BOOL←TJOINTS(P,"GOBLEDEEGOOK");
      TYPE "THRU: TJOINTS" EOM;
      ∀ P|POINT⊗S≡P ∧ (¬(PεSOP)) DO BOOL←XZANDKZ(P);
      TYPE "THRU: XZANDKZ" EOM;
      ∀ P|POINT⊗S≡P ∧ (¬(PεSOP)) DO BOOL←ARROWS(P);
      TYPE "THRU: ARROWS" EOM;
      ∀ P|POINT⊗S≡P ∧ (¬(PεSOP)) DO BOOL←WHYS(P);
      TYPE "THRU: WHYS" EOM;
      ∀ P|POINT⊗S≡P ∧ (¬(PεSOP)) DO BOOL←ELZ(P);
      TYPE "THRU: ELZ" EOM;

α this above sequence creates the initial nodes for the scene;

      GOODTZ4BAD;
      INHIBIT;
α	IF ¬RUN
	THEN SHOWDATA;
      DPYBRK;
α	 LPAIR HACK
look for matched BADL's and set up a node called LPAIR
whose datum is the two colinear lines.
[NOTE: this creates a node for each of the BADL vertices.]

Quite obviously, this is not the right thing to do...a line
between the BADLs should be created and added to the created
nodes.
;

DPYTELL( "FIXUP 3:LPAIR HACK" );
LPAIRS;

α set up links between nodes in the graph of the form:
	LINK⊗<node>≡<node>
;

DPYTELL( "INITIAL LINK STRUCTURE.");

∀ X,Y|	NODE⊗GRAPH≡X ∧ NODE⊗GRAPH≡Y ∧ (X≠Y) ∧
	(¬(LINK⊗Y≡X)) ∧ (∂(X)∩∂(Y)≠PHI) DO
	MAKE LINK⊗X≡Y;
DPYBRK;

α  eliminate links by merging:
this is where two nodes are merged into one node if either
node has a link to the other node...the clumps so created
eventually are merged with other clumps or become the bodies
of the scene.
;

DPYTELL( "FIRST MERGE OF LINKS." );

LAB4:
∀ X,Y|	NODE⊗GRAPH≡X ∧ NODE⊗GRAPH≡Y ∧
	(X≠Y) ∧ (LINK⊗X≡Y ∨ LINK⊗Y≡X) DO
BEGIN "FIRST MERGE"
	MERGE(0);
	MERGE_NODE(Y,X);
	GO TO LAB4;
	END "FIRST MERGE";

TYPE "NUMBER CLUMPS IN SCENE: "&CVS(LENGTH(NODE⊗GRAPH)) EOM;
DPYBRK;

α	DISJOINT;

TYPE "CONTENTS OF TSTEMS SET" EOM;
∀ P|PεTSTEMS DO TYPE PRINTNAME(P)&" " EOS;
TYPE "DONE" EOM;

α merge disjoint nodes that each contain a TJOINT,
where the TJOINTs have colinear TSTEMs;

DPYTELL("CONNECT DISJOINT PARTS");
DPYBOOL←FALSE;

DISJOINT;

α DISPLAY;
      IF DEBUG2 ∧ DPYBOOL
      THEN ⊂ DPYSET(DPYBB);
	∀ L|EDGE⊗SCENE≡L DO DPYL(L);
	∀ L|EDGE⊗SCENE≡L DO DPYLN(L);
	DPYOUT(APOG);⊃;
      DPYLAB("MERGE 1");
      HYDPOG(APOG);
      DPYBOOL←FALSE;
α FINIS;

α	FIXUP 1, FIXUP 2
for any node of the graph which is a single TJOINT where one
of the colinear portions is also a part of a BADL and the other line
of the BADL belongs to some other node of the graph, merge the TJOINT
node with this node;

DPYTELL( "FIXUP 1:TJOINT AND BADL");
DPYBOOL←FALSE;

FIXUP1;

IF DPYBOOL ∧ DEBUG2
THEN DPYLAB("MERGE 2");
DPYBOOL←FALSE;

α	FIXUP 2
this case handles a dangling GOODL that would otherwise be
discarded if both edges of the GOODL are also stems of TJOINTs;

DPYTELL( "FIXUP 2:DANGLING GOODL");
DPYBOOL←FALSE;

FIXUP2;

IF DEBUG2 ∧ DPYBOOL
THEN DPYLAB("MERGE 3");
DPYBOOL←FALSE;

α	IF DEBUG2
	THEN DPYNODES;

α this is a crock !!!!;		
DPYBOOL←FALSE;
∀ X|NODE⊗GRAPH≡X DO
 IF LENGTH(DATUM(X))=2
  THEN BEGIN "CROCK"
	ERASE NODE⊗GRAPH≡X;
	DPYBOOL←TRUE;
	MERGE(4);
	END "CROCK";
IF DEBUG2 ∧ DPYBOOL
THEN DPYLAB("MERGE 4");
DPYBOOL←FALSE;

TYPE "NUMBER OF NODES IN SCENE: "&CVS(LENGTH(NODE⊗GRAPH)) EOM;
S1←PHI;
∀ X|NODE⊗GRAPH≡X DO S1←S1 ∪ DATUM(X);
TYPE "NUMBER OF LINES IN SCENE:"&CVS(LENGTH(LINE⊗S)) EOM;
TYPE "NUMBER OF UNACCOUNTED FOR LINES:"&CVS(LENGTH(LINE⊗S)-LENGTH(S1)) EOM;

α	TRY1, TRY2, TRY3
this is concerned with the lines of the scene which
are not accounted for by the graph node datums...if the line
is between TJOINTs or BADAROs or combos of these, then find
the first graph node having a line colinear with this line
and put the line into that node;

β	DPYTELL("TRY TO COMPLETE FACES");

β	DPYINFO("TRY 0");
TRY0;

β	DPYINFO("TRY 1");
TRY1;

α	TRY2
if some of the lines of a non-background regions are
contained in any node, then add the rest of the
region's lines to that node.
;

β	DPYINFO("TRY 2");
TRY2;

α	TRY 3
NOTE: THE SCENE MUST BE COPIED.  THIS IS A (ORBAN) CROCK.

at this point, the clumps and nodes can't be merged any more...
each node of the graph is made into a LOCAL body:
	BMATCH⊗<node>≡<body>
	BODY⊗S≡<body item>
		LINE⊗<body>≡<line>	(for each element of node datum)
		ENDPT⊗<line>≡<point>
		POINT⊗<body>≡<line endpoint>
;

β	DPYINFO("TRY 3");
∀ X|NODE⊗GRAPH≡X DO
BEGIN	"TRY 3"
  B←NEW(FOURBY4);
  NEW_PNAME(B,GENSYM(NEWB));
  MAKE BODY⊗S≡B;
  MAKE BMATCH⊗X≡B;

  ∀ L|LεDATUM(X) DO
  BEGIN
    MAKE LINE⊗B≡L;
    ∀ P|ENDPT⊗L≡P ∧ (¬ POINT⊗B≡P) DO
	MAKE POINT⊗B≡P;
    END;
    END "TRY 3";

β	IF DEBUG2
β	THEN DPYLAB("BODIES CREATED.");

α what is now needed are:
	FACE⊗B≡<face>	(m times)
		BOUNDARY⊗<face>≡<line>	(k times)
		CORNER⊗<face>≡<point>	(k times)
;

α	TRY4, TRY5
assign the regions of the scene to bodies;

DPYBOOL←FALSE;
β	DPYINFO("TRY 4");
TRY4;

α		try 5
This looks like it tries to remove the lines
between bad vertices from a region.;

DPYBOOL←FALSE;
β	DPYINFO("TRY 5");
TRY5;

α	FIXUP THE LOCAL DATA STRUCTURE, SPLICE;

α erase body lines that aren't boundaries of body regions;

DPYTELL("FIXUP LOCAL STRUCTURE");
∀ B,L|BODY⊗S≡B ∧ LINE⊗B≡L DO
IF (BOUNDARY`L) ∩ (FACE⊗B)=PHI
THEN BEGIN
	TYPE "REMOVING LINE "&PRINTNAME(L)&
		  " FROM BODY "&PRINTNAME(B) EOM;
	DPYBOOL←TRUE;
	ERASE LINE⊗B≡L;
	END;

β IF DEBUG2 ∧ DPYBOOL
β THEN BEGIN
β	DPYSET(DPYBB);
β	∀ L|LINE⊗S≡L DO DPYL(L);
β	∀ L|LINE⊗S≡L DO DPYLN(L);
β	DPYOUT(APOG);
β	DPYLAB("REMOVED LINES");
β	HYDPOG(APOG);
β	END;

α erase face boundaries that aren't lines of the body;

∀ B,F,L|BODY⊗S≡B ∧ FACE⊗B≡F ∧ BOUNDARY⊗F≡L ∧ (¬LINE⊗B≡L) DO
       ERASE BOUNDARY⊗F≡L;

α erase face corners that aren't points of the face's body;

∀ B,F,P|BODY⊗S≡B ∧ FACE⊗B≡F ∧ CORNER⊗F≡P ∧ (¬POINT⊗B≡P) DO
       ERASE CORNER⊗F≡P;

α merge colinear touching lines of a body into one line;

SPLICE;

β	DPYTELL("SEGMENTATION COMPLETE");
β	DPYINFO(CVS(LENGTH(BODY⊗S))&" BODIES FOUND");
β	DPYBRK;

α	ABOVE, OCCLUDERS, EXTERIOR;

BEGIN "HELPFUL"

SET TS2,TS3,S2,S3;

DPYTELL("BODIES ABOVE");
∀ X,Y|ABOVE⊗X≡Y ∧ LINE⊗S≡X ∧ LINE⊗S≡Y DO
BEGIN "HABOVE"
	ASSIGN B1|LINE⊗B1≡X HOLDS;
	ASSIGN B2|LINE⊗B2≡Y HOLDS;
	IF B1=B2
	THEN TYPE PRINTNAME(B1)&" IS ABOVE ITSELF." EOM
	ELSE BEGIN
		TYPE PRINTNAME(B2)&" IS ABOVE "&PRINTNAME(B1) EOM;
		MAKE ABOVE⊗B1≡B2;
		ERASE ABOVE⊗X≡Y;		END;
	END "HABOVE";

DPYTELL("BODIES OCCLUDED");
α the occlugers:	;
	S2←OCCLUDER⊗ANY;
α the occluded:		;
	S3←OCCLUDER`ANY;
∀ B1,B2| BODY⊗S≡B1 ∧ BODY⊗S≡B2 ∧ (B1≠B2) ∧
	 (¬OCCLUDER⊗B1≡B2) ∧ (¬OCCLUDER⊗B2≡B1) DO
IF S2∩LINE⊗B1 ≠ PHI
THEN IF S3∩LINE⊗B2 ≠ PHI
     THEN BEGIN
		TYPE PRINTNAME(B1)&" OCCLUDES "&PRINTNAME(B2) EOM;
		MAKE OCCLUDER⊗B2≡B1;
		END
     ELSE
ELSE IF S3 ∩ LINE⊗B1 ≠ PHI
     THEN IF S2 ∩ LINE⊗B2 ≠ PHI
	  THEN BEGIN
		TYPE PRINTNAME(B2)&" OCCLUDES "&PRINTNAME(B1) EOM;
		MAKE OCCLUDER⊗B1≡B2;
		END;
∀ L|LINE⊗ANY≡L DO ERASE OCCLUDER⊗L≡ANY;

DPYLAB("ABOVE,,OCCLUDING");
END "HELPFUL";

	DPYTELL("EXTERIOR.");
∀ B|BODY⊗S≡B DO
BEGIN "EXTERIOR"
	BACKSET←PHI;
	∀ L|LINE⊗B≡L DO
	BEGIN 
		SSET←BOUNDARY`L;
		IF LENGTH(SSET)=1
		THEN PUT L IN BACKSET;
		END;
	XS←NEW(BACKSET);
	MAKE  EXTERIOR⊗B≡XS;
	END "EXTERIOR";

α	PROPOSER - FIX UP THE BODIES
A MORE ORGANIZED METHOD IS NEEDED FOR APPLING THESE HEURISTICS
AND IN THE PROPER ORDER - E.G.  BASED ON:
	NUMBER OF DANGLING EDGES
	NUMBER OF INCOMPLETE FACES
	NUMBER OF COMPLETE FACES VERSES THE NUMBER EXPECTED

The plan is to put all this region stuff with the SEGMENTER region stuff
together in one job so that the needed info (PARENT, SON, etc.) doesn't
have to be copied back and forth.  The algorithms applied:
EXTEND		connect dangling colinear edges along a face boundary
ADDCORNER	put a corner at the intersection of two dangling edges
ADDLINE		put a line connecting matched GOODLs
EXT_LINE	extend a dangling face edge to a face corner
ADDEL		add a GOODL to connect a dangling edge and a face corner
EXT_FACE	extend two vertical dangling face edges to base
ADDFACE		add the phantom face bounded by visible faces
;

BEGIN "PROPOSER"
∀ B|BODY⊗S≡B DO
BEGIN "COMPLETE"
β	DPYTELL("PROPOSER:"&PRINTNAME(B));

β	DPYINFO("EXTEND.");
β	DPYB(B);
β	DPYLAB("BEFORE EXTENDING.");
	WHILE EXTEND(B) DO
	BEGIN "SHOW EXTEND"
β		HYDPOG(APOG);
β		DPYB(B);
β		DPYLAB("EXTENDING");
β		HYDPOG(APOG);
		END "SHOW EXTEND";

β	DPYINFO("ADD ""OBVIOUS"" CORNERS.");
	NEWPOINTS←PHI;
β	DPYB(B);
β	DPYLAB("BEFORE CORNERS ADDED.");
	WHILE ADDCORNER(B) DO
	BEGIN "ADDCORNER"
β		HYDPOG(APOG);
β		DPYB(B);
β		DPYLAB("ADDING CORNERS");
β		HYDPOG(APOG);
β		END "ADDCORNER";

β	DPYINFO("ADD ""OBVIOUS"" LINES");
β	DPYB(B);
β	DPYLAB("BEFORE LINES ADDED");
	WHILE ADDLINE(B) DO
	BEGIN "ADDLINE"
β		HYDPOG(APOG);
β		DPYB(B);
β		DPYLAB("ADDING LINE" );
β		HYDPOG(APOG);
		END "ADDLINE";

β	DPYINFO("EXT LINE.");
β	DPYB(B);
β	DPYLAB("BEFORE EXTENDING");
	WHILE EXT_LINE(B) DO
	BEGIN "EXT LINE"
β		HYDPOG(APOG);
β		DPYB(B);
β		DPYLAB("EXTENDING");
β		HYDPOG(APOG);
		END "EXT LINE";

β	DPYINFO("ADD ""OBVIOUS"" ELS");
β	DPYB(B);
β	DPYLAB("BEFORE ELS ADDED");
	WHILE ADDEL(B) DO
	BEGIN "ADDEL"
β		HYDPOG(APOG);
β		DPYB(B);
β		DPYLAB( "ADDING EL" );
β		HYDPOG(APOG);
		END "ADDEL";

β	DPYINFO("EXT FACE.");
β	DPYB(B);
β	DPYLAB("BEFORE EXTENDING");
	WHILE EXT_FACE(B) DO
	BEGIN "EXT FACE"
β		HYDPOG(APOG);
β		DPYB(B);
β		DPYLAB("EXTENDING");
β		HYDPOG(APOG);
		END "EXT FACE";

β	DPYINFO("ADD FACE.");
β	DPYB(B);
β	DPYLAB("BEFORE ADDING");
	WHILE ADDFACE(B) DO
	BEGIN "ADD FACE"
β		HYDPOG(APOG);
β		DPYB(B);
β		DPYLAB("ADDING");
β		HYDPOG(APOG);
		END "ADD FACE";
β	HYDPOG(APOG);

	END "COMPLETE";
END "PROPOSER";


α	GLOBAL STRUCTURE FOR BODIES:
This is the first step in the new COMPLEX scheme.
The structure passed to RECOGNIZER is higher level
oriented - i.e. body oriented:
	BACKGROUND⊗S≡<region>
		BOUNDARY⊗<background>≡<line>
		CORNER⊗<background>≡<point>
	BODY⊗S≡<body>
		LINE⊗<body>≡<line>
		POINT⊗<body>≡<point>
		FACE⊗<body>≡<face>
			BOUNDARY⊗<face>≡<line>
			CORNER⊗<face>≡<point>
	ABOVE⊗<body>≡<body>
	OCCLUDER⊗<body>≡<body>
Eventually, this part will be done in the REGION COMPLETER
[see, this region stuff tries to divide complex regions between
bodies, while the region stuff in RECOGNIZER tries to complete
regions for the bodies.]
program.
;
α	SET UP GLOBAL BODY STRUCTURE
;

DPYLAB("BEFORE GLOBAL TRANSFER");
∀ B|BODY⊗S≡B DO
BEGIN "GASS"
SET ITEMVAR GBASE;
SAFE REAL ARRAY ITEMVAR GB,GF,F,GP,P;
REAL ITEMVAR GL,L;


β	DPYTELL("GLOBALS FOR "&PRINTNAME(B));

GB←GLB NEW(FOURBY4);
GLB MAKE BODY⊗S≡GB;
MAKE OMATCH⊗GB≡B;
TYPE "SET UP GLOBAL ASSOC FOR "&PRINTNAME(B) EOM;

GBASE←GLB NEW(PHI);
GLB MAKE BASE⊗GB≡GBASE;

α	DPYINFO("GP.");
∀ P|POINT⊗B≡P DO
BEGIN "GP";
	GP←GLOBAL NEW(SIZE7);
	ARRTRAN(GLB ∂(GP),∂(P));
	MAKE OMATCH⊗GP≡P;
	GLB MAKE POINT⊗GB≡GP;
	END "GP";

β	DPYINFO("GL.");
∀ L|LINE⊗B≡L DO
BEGIN "GL";
	GL←GLOBAL NEW(0.0);
	MAKE OMATCH⊗GL≡L;
	GLB MAKE LINE⊗GB≡GL;
	END "GL";

β	DPYINFO("GE.");
∀ L|LINE⊗B≡L DO
 ∀ P|ENDPT⊗L≡P DO
 BEGIN "GE";
	ASSIGN GL|OMATCH⊗GL≡L  HOLDS;
	ASSIGN GP|OMATCH⊗GP≡P  HOLDS;
	GLB MAKE ENDPT⊗GL≡GP;
	END "GE";

β	DPYINFO("GF.");
∀ F|FACE⊗B≡F DO
BEGIN "GF";
	GF←GLOBAL NEW(SIZE4);
	MAKE OMATCH⊗GF≡F;
	GLB MAKE FACE⊗GB≡GF;
	END "GF";

β	DPYINFO("GB.");
∀ F|FACE⊗B≡F DO
IF (BOUNDARY⊗F)=PHI
THEN TYPE "NO BOUNDARIES FOR FACE "&PRINTNAME(F) EOM
ELSE ∀ L|BOUNDARY⊗F≡L DO
BEGIN "GB";
	ASSIGN GF|OMATCH⊗GF≡F HOLDS;
	ASSIGN GL|OMATCH⊗GL≡L HOLDS;
	GLB MAKE BOUNDARY⊗GF≡GL;
	END "GB";

β	DPYINFO("GC.");
∀ F|FACE⊗B≡F DO
IF (CORNER⊗F)=PHI
THEN TYPE "NO CORNERS FOR FACE "&PRINTNAME(F) EOM
ELSE ∀ P|CORNER⊗F≡P DO
BEGIN "GC";
	ASSIGN GF|OMATCH⊗GF≡F HOLDS;
	ASSIGN GP|OMATCH⊗GP≡P HOLDS;
	GLB MAKE CORNER⊗GF≡GP;
	END "GC";

END "GASS";

α  OTHER GLOBAL ASSOCIATIONS:
	ABOVE⊗<global body>≡<global body>
	OCCLUDER⊗<global body>≡<global body>
;

β	DPYTELL("GABO.");
∀ B1,B2|ABOVE⊗B1≡B2 DO
BEGIN "GABO";
	ASSIGN GB1|OMATCH⊗GB1≡B1 HOLDS;
	ASSIGN GB2|OMATCH⊗GB2≡B2 HOLDS;
	GLB MAKE ABOVE⊗GB1≡GB2;
	END "GABO";

β	DPYTELL("GOCC.");
∀ B1,B2|OCCLUDER⊗B1≡B2 DO
BEGIN "GOCC";
	ASSIGN GB1|OMATCH⊗GB1≡B1 HOLDS;
	ASSIGN GB2|OMATCH⊗GB2≡B2 HOLDS;
	GLB MAKE OCCLUDER⊗GB1≡GB2;
	END "GOCC";

β	DPYDONE;

END "MP SEGMENT";

α	PROGRAM EXECUTION;

IF ¬YES_SEG
THEN PUT_DATA(0,0,"SEGMENTER");
YES_SEG←TRUE;

ADCOR1←5.0;
ADCOR2←10.0;

LPAIR←NEW(0);	NEW_PNAME(LPAIR,"LPAIR");
TPAIR←NEW;	NEW_PNAME(TPAIR,"TPAIR");
NEWR←NEW(0);	NEW_PNAME(NEWR,"R");
NEWF←NEW(0);	NEW_PNAME(NEWF,"F");
NEWP←NEW(0);	NEW_PNAME(NEWP,"P");
NEWB←NEW(0);	NEW_PNAME(NEWB,"BOD");
NEWL←NEW(0);	NEW_PNAME(NEWL,"L");
T_STEM←NEW;	NEW_PNAME(T_STEM,"TSTEM");
NOFLAVOR←NEW;	NEW_PNAME(NOFLAVOR,"NOFLAVOR");
TMPATR←NEW;
EXTERIOR←NEW;	NEW_PNAME(EXTERIOR,"EXTERIOR");
REASON←NEW;
BMATCH←NEW;	NEW_PNAME(BMATCH,"BMATCH");
CMATCH←NEW;	NEW_PNAME(CMATCH,"CMATCH");
IMATCH←NEW;	NEW_PNAME(IMATCH,"IMATCH");
NMATCH←NEW;	NEW_PNAME(NMATCH,"NMATCH");
OMATCH←NEW;	NEW_PNAME(OMATCH,"OMATCH");
NFLAVOR←NEW;	NEW_PNAME(NFLAVOR,"NFLAVOR");
MATCH←NEW;	NEW_PNAME(MATCH,"MATCH");
MATCH2←NEW;
GRAPH←NEW;	NEW_PNAME(GRAPH,"GRAPH");
NODE←NEW;	NEW_PNAME(NODE,"NODE");
LINK←NEW;	NEW_PNAME(LINK,"LINK");
ITEM1←NEW;

β	DPYINIT;
OUTSTR("SEGMENTER (JOB2) UP AND READY"&↓);

WHILE ¬RUN DO
BEGIN "DEBUG LOOP"
	SEGMENT;
	DISKOUT;
	CALL(0,"EXIT");
END "DEBUG LOOP";

WHILE TRUE DO
    BEGIN
       MESS1←GET_ENTRY('120,NULL,"SEGMENTER",NULL);
       MESS1←QUEUE('600,MESS1);
    END;

END "SEGMENTER" ;